package com.xbongbong.crm.abstracts;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.data.service.RichTextService;
import com.xbongbong.crm.service.FormDataFineClueService;
import com.xbongbong.paas.data.service.SerialNoService;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataRepeatDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.crm.service.FormDataFineClueService;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.SaveFormExplainPojo;
import com.xbongbong.pro.formdata.pojo.vo.BeforeSaveVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.help.AnalyticalHelp;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.service.toolbox.help.SaasSaveHelper;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/02/15 14:06
 */
@Component
public abstract class AbstractFineClueService extends AbstractCrmAddDataService implements FormDataFineClueService {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractFineClueService.class);

    @Resource
    private SaasSaveHelper saasSaveHelper;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private AnalyticalHelp analyticalHelp;
    @Resource
    private SerialNoService serialNoService;
    @Resource
    private RichTextService richTextService;

    /**
     * 保存富文本
     *
     * @param formDataAddDTO
     * @param paasFormDataEntity
     * @param richTextData 富文本数据
     * @throws XbbException
     */
    protected void saveRichText(FormDataAddDTO formDataAddDTO, PaasFormDataEntity paasFormDataEntity,Object richTextData) throws XbbException{
        richTextService.saveFormRichText(formDataAddDTO, paasFormDataEntity, richTextData);
    }

    /**
     * 移除富文本
     *
     * @param data Json数据
     * @return 富文本数据
     * @throws XbbException
     */
    protected Object removeRichText(JSONObject data) throws XbbException{
        return FormDataUtil.removeRichText(data);
    }

    @Override
    public BeforeSaveVO beforeSaveNoValidate(FormDataAddDTO formDataSaveDTO) throws XbbException {
        BeforeSaveVO beforeSaveVO = new BeforeSaveVO();
        try {
            Integer businessType = formDataSaveDTO.getBusinessType();
            JSONObject data = formDataSaveDTO.getDataList();
            // todo 第二期处理：权限和数据量的校验
//            validatePermission(formDataSaveDTO);
            PaasFormEntityExt paasFormEntityExt = getFormEntity(formDataSaveDTO);
            SaveFormExplainPojo saveFormExplainDTO = getExplainMap(formDataSaveDTO.getFormId(), formDataSaveDTO.getCorpid());
            Map<String, FieldAttrEntity> explainMap = saveFormExplainDTO.getExplainMap();
            if (data.containsKey("isBringCustomer")) {
                // 线索转换客户操作，这个参数决定是否要将线索的跟进记录带给客户，因为下面data里面需要remove掉，所以这边拿出来传给dto
                Integer isBringCustomer = data.getInteger("isBringCustomer");
                Long clueId = data.getLong("clueId");
                formDataSaveDTO.setIsBringCustomer(isBringCustomer);
                formDataSaveDTO.setClueId(clueId);
            }
            // 获取严控下的流水号以及系统字段设置
            ValidateDataDTO validateDataDTO = new ValidateDataDTO();
            // 获取严控下的流水号以及系统字段设置
            BeanUtil.copyProperties(formDataSaveDTO, validateDataDTO);
            validateDataDTO.setExplainMap(explainMap);
            //销项发票、进项发票、回款单、付款单金额明细处理
            SheetTypeEnum sheetTypeEnum = SheetTypeEnum.getByBusinessType(businessType);
            JSONArray amountDetail = saasSaveHelper.getAmountDetail4Check(null, sheetTypeEnum, data,businessType);
            formDataSaveDTO.setAmountDetail(amountDetail);
            validateDataDTO.setAmountDetail(amountDetail);

            validateDataDTO.setData(data);
            validateDataDTO.setOwnerIds(formDataSaveDTO.getOwnerId());
            // 解析数据
            ProSaveHelp.analyticalData(validateDataDTO);
            // 设置特殊参数，主要是报价单和产品
            setSpecialParam(formDataSaveDTO, validateDataDTO);
            // 校验必填字段
//            formDataValidateDataHelp.validateData(validateDataDTO);
            // 特殊：客户和线索的名称和电话是否判重要去表单配置表查询（此处重新给 explainMap 中的名称电话中的 noRepat 赋值）
            if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                // 判重校验
                FormDataRepeatDTO formDataRepeatDTO = new FormDataRepeatDTO();
                BeanUtil.copyProperties(validateDataDTO, formDataRepeatDTO);
                //需要校验查重字段如下：客户名称、简称、电话字段
                List<String> noRepeatAttrList = new ArrayList<>();
                noRepeatAttrList.add(StringConstant.NAME);
                noRepeatAttrList.add(StringConstant.PHONE);
                noRepeatAttrList.add("text_2");//客户简称
                List<FieldAttrEntity> explainList = saveFormExplainDTO.getExplainList();
                explainList.removeIf(item -> (Objects.equals(item.getEditHide(), BasicConstant.ONE) || !Objects.equals(item.getIsOpen(), BasicConstant.ONE) || Objects.equals(item.getFieldType(), FieldTypeEnum.USER.getType())));
                Map<String, FieldAttrEntity> formExplainMap = ExplainUtil.getSubFormExplainMapByList(explainList);

                for (String attr : noRepeatAttrList) {
                    FieldAttrEntity fieldAttr = formExplainMap.get(attr);
                    if (Objects.isNull(fieldAttr)) {
                        continue;
                    }
                    if (Objects.nonNull(fieldAttr.getNoRepeat()) && Objects.equals(fieldAttr.getNoRepeat(), BasicConstant.ONE)) {
                        if (Objects.equals(StringConstant.PHONE,attr)) {
                            if (CollectionsUtil.isNotEmpty(formDataSaveDTO.getFineCluePhone())) {
                                formDataRepeatDTO.setAttr(StringConstant.PHONE_ATTR);
                                formDataRepeatDTO.setSubAttr(StringConstant.PHONE_TEL_ATTR);
                                formDataRepeatDTO.setSubValueList(formDataSaveDTO.getFineCluePhone());
                                //为了兼容底层方法改字段值的校验。这里传的值没具体意义
                                formDataRepeatDTO.setValue(BasicConstant.ONE);
                                formDataValidateDataHelp.repeat(formDataRepeatDTO, validateDataDTO, fieldAttr);
                            }
                        } else {
                            Object attrData = data.get(attr);
                            if (Objects.nonNull(attrData)) {
                                formDataRepeatDTO.setValue(data.get(attr));
                                formDataRepeatDTO.setAttr(attr);
                                formDataValidateDataHelp.repeat(formDataRepeatDTO, validateDataDTO, fieldAttr);
                            }
                        }
                    }
                }
            }

            // 校验各个业务的逻辑 todo 需要重构，注意重构方式
            // TODO 不懂为啥标签要在saasSaveHelp.beforeSave里解析，为什么不放在ProSaveHelp.analyticalData
            SaveFormatHelp.dealLabelData(validateDataDTO.getData(), explainMap);
            analyticalHelp.beforeSave(validateDataDTO);
            // 这里再重新赋值所有字段的
            validateDataDTO.setExplainMap(explainMap);

            beforeSaveVO.setExplainMap(explainMap);
            // 产品可见人和可见部门
            if ( Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode()) ) {
                formDataSaveDTO.setVisbleDept(validateDataDTO.getVisbleDept());
                formDataSaveDTO.setVisbleUser(validateDataDTO.getVisbleUser());
            }
            if (CollectionsUtil.isNotEmpty(amountDetail)) {
                SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = validateDataDTO.getSaasNeedRedundantAttrPoJo();
                saasNeedRedundantAttrPojo.setAmountDetail(amountDetail);
                validateDataDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
            }
            PaasFormDataEntity paasFormDataEntity = serialNoService.setSerialNo(formDataSaveDTO, formDataSaveDTO.getCorpid(), formDataSaveDTO.getBusinessType(), validateDataDTO.getExplainMap());
            paasFormDataEntity.setCorpid(formDataSaveDTO.getCorpid());
            paasFormDataEntity.setAppId(paasFormEntityExt.getAppId());
            paasFormDataEntity.setMenuId(paasFormEntityExt.getMenuId());
            paasFormDataEntity.setFormId(paasFormEntityExt.getId());
            String ownerId = formDataSaveDTO.getUserId();
            paasFormDataEntity.setOwnerId(ownerId);
            // 所属部门的id，由前端传入 所属部门不可见，前端拿不到时，卡特建议直接赋值-1
            Long departmentId = validateDataDTO.getDepartmentId() == null ? -1L : validateDataDTO.getDepartmentId();
            paasFormDataEntity.setDepartmentId(departmentId);
            formDataSaveDTO.setDepartmentId(departmentId);
            if ( Objects.nonNull(formDataSaveDTO.getOwnerId()) && !formDataSaveDTO.getOwnerId().isEmpty() ) {
                paasFormDataEntity.setOwnerId(Objects.toString(formDataSaveDTO.getOwnerId().get(0).getId(), ""));
            }
            paasFormDataEntity.setSerialNo(formDataSaveDTO.getSerialNo());
            paasFormDataEntity.setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());

            paasFormDataEntity.setData(data);
            paasFormDataEntity.setCreatorId(formDataSaveDTO.getUserId());
            if ( StringUtil.isNotEmpty(FastJsonHelper.getStringFromFormData(formDataSaveDTO.getDataList(), FieldTypeEnum.CREATORID.getAlias())) ) {
                paasFormDataEntity.setCreatorId(FastJsonHelper.getStringFromFormData(formDataSaveDTO.getDataList(), FieldTypeEnum.CREATORID.getAlias()));
                formDataSaveDTO.getDataList().remove(FieldTypeEnum.CREATORID.getAlias());
            }
            formDataSaveDTO.setExplainMap(explainMap);
            formDataSaveDTO.setSaasNeedRedundantAttrPoJo(validateDataDTO.getSaasNeedRedundantAttrPoJo());
            beforeSaveVO.setPaasFormEntityExt(paasFormEntityExt);
            beforeSaveVO.setExplainList(saveFormExplainDTO.getExplainList());
            beforeSaveVO.setSaasNeedRedundantAttrPojo(validateDataDTO.getSaasNeedRedundantAttrPoJo());
            beforeSaveVO.setPaasFormDataEntity(paasFormDataEntity);

            beforeSaveVO.setNoApprovalRequired(BasicConstant.ONE);

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("abstractFormDataService.beforeSave 出错",e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return beforeSaveVO;
    }
}
